
#ifndef IIWIDGETS_H
#define IIWIDGETS_H

#include "iicommon.hpp"
#include "../iwidgets.hpp"
#include "iiapplication.hpp"

extern "C" {
#include <TinyWidgets/tnWidgets.h>
#include <TinyWidgets/tnCompatibility.h>
}

/////////////
// Windows //
/////////////

// Qt window

class QIWindow :  public QIWidget, public IWindow
{
	Q_OBJECT
	
	QI_WIDGET(,QIWidget)
	
public:
	QIWindow(QIWidget *parent, const char *title, int x, int y) :
		QWidget(parent)
	{
		setTitle(title);
		setPosition(x, y);
		QWidget::setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint);
	}

	void setPosition(int x, int y)
	{
		QWidget::move(x, y);
	}

	void setTitle(const char *title)
	{
		const QString wtitle(title);
		QWidget::setWindowTitle(wtitle);
	}

protected:
	class QCloseEvent;
	
	void closeEvent(QCloseEvent *)
	{
		std::cout << "closing!\n";
		exit(0); //todo
	}

};

class QIMainWindow : public QIWindow
{
	
	class QCloseEvent;

public:
	QIMainWindow(const char *title, int x, int y) : QIWindow(NULL, title, x, y) { }
	
protected:

	// todo
	virtual void closeEvent(QCloseEvent *)
	{
		std::cout << "close!\n";
		//Todo!: QtCorApplication::quit Application quit
		exit(0); 
	}
};

// TNW window

class TIWindow : public IWindow, public TIWidget {

public:
	TIWindow(TIWidget *parent, const char *title, int x, int y)
	{
		Create(__FILE__, title, TN_WINDOW, **parent, x, y, TN_CAPTION, title, TN_END);
	}

	TIWindow(TN_WIDGET *parent, const char *title, int x, int y)
	{
		Create(__FILE__, title, TN_WINDOW, parent, x, y, TN_CAPTION, title, TN_END);
	}
	
	TIWindow(TN_WIDGET *window, const char *title)
	{
		m_pWidget = window;
		setTitle(title);
	}

	void setPosition(int x, int y)
	{
		// todo
	}

	void setTitle(const char *title)
	{
		// FIXME: seems not to work
		tnSetWindowTitle(THIS_TWG, const_cast<char*>(title));
	}

};


/////////////////
// Radio group //
/////////////////

#include <QGroupBox>

// Qt radio group

class QIRadioGroup : public IRadioGroup, public QGroupBox, public QIWidget {

	QI_WIDGET(,QGroupBox)

public:
	QIRadioGroup(QIWidget *parent, const QString &label, int x, int y) : QGroupBox(label, parent)
	{
		QGroupBox::move(x, y);
	}

	void setCaption(const char *c)
	{
		const QString capt(c);
		QGroupBox::setTitle(capt);
	}
};

// TWN radio group

class TIRadioGroup : public IRadioGroup, public TIWidget {

public:
	
	tiobj_constructor(RadioGroup, TN_RADIOBUTTONGROUP)

	void setCaption(const char *c)
	{
		tnSetWidgetCaption(THIS_TWG, const_cast<char*>(c));	
	}
};

/////////////
// Buttons //
/////////////

#include <QPushButton>

extern "C" {
#include <TinyWidgets/tnButton.h>
}
	
// Qt button

class QIButton : public IButton, public QPushButton, public QIWidget {

	QI_WIDGET(,QPushButton)

public:
	QIButton(QIWidget *parent, const QString &label, int x, int y) : QPushButton(label)
	{
		rtti_qiradiogroup_parent(QPushButton);
		QPushButton::move(x, y);
	}

	virtual void setCaption(const char *caption)
	{
		const QString txt(caption);
		QPushButton::setText(txt);
	}

	virtual std::string caption() const
	{
		return QPushButton::text().toStdString();
	}
		
};

// TNW button	

class TIButton : public IButton, public TIWidget {

public:
	TIButton(const char* label, TIWidget *parent, int x, int y) {
		Create(__FILE__, label, TN_BUTTON, **parent, x, y, TN_CAPTION, label, TN_END); 
	}

	virtual void setCaption(const char *caption)
	{
		tnSetButtonCaption(THIS_TWG, const_cast<char*>(caption));
	}
	
	virtual std::string caption() const
	{
		return std::string(tnGetWidgetCaption(THIS_TWG));
	}
};


////////////
// Labels //
////////////

#include <QLabel>

// Qt labels

class QILabel : public ILabel, public QLabel, public QIWidget {

	QI_WIDGET(,QLabel)

public:
	QILabel(QIWidget *parent, const QString &label, int x, int y) : QLabel(label)
	{
		rtti_qiradiogroup_parent(QLabel);
		QLabel::move(x, y);
	}

	void setText(std::string &txt) {
		const QString text(txt.c_str());
		QLabel::setText(text);
	}

	std::string getText() {
		return QLabel::text().toStdString();
	}	

};

// TNW labels
class TILabel : public ILabel, public TIWidget {

public:

	TILabel(const char *title, TIWidget *parent, int x, int y)
	{
		Create(__FILE__, title, TN_LABEL, **parent, x, y, TN_CAPTION, title, TN_END);
		setBgColor(IColor::Grey);
	}

	void setText(std::string &txt)
	{
		tnSetLabelCaption(THIS_TWG, const_cast<char*>(txt.c_str()));
	}

	std::string getText() 
	{
		//todo
	}
};


/////////////////
// Checkbutton //
/////////////////

#include <QCheckBox>

// Qt check button

class QICheckButton : public ICheckButton, public QCheckBox, public QIWidget {

	QI_WIDGET(,QCheckBox)

public:
	QICheckButton(QIWidget *parent, const QString &label, int x, int y) : QCheckBox(label)
	{
		rtti_qiradiogroup_parent(QCheckBox);
		QCheckBox::move(x, y);
	}

	void setCaption(const char *label) 
	{
		const QString lbl(label);
		QCheckBox::setText(lbl);
	}

	std::string getCaption()
	{
		return QCheckBox::text().toStdString();
	}

	bool checked()
	{
		return QCheckBox::isChecked();
	}

	void setChecked(bool checked)
	{
		QCheckBox::setChecked(checked);
	}
};

// TNW check button

class TICheckButton : public ICheckButton, public TIWidget {

public:

	tiobj_constructor(CheckButton, TN_CHECKBUTTON)

	void setCaption(const char *label)
	{
		tnSetCheckButtonCaption(THIS_TWG, const_cast<char*>(label));
	}

	std::string getCaption() 
	{
		return std::string(tnGetWidgetCaption(THIS_TWG));
	}

	bool checked() 
	{
		return THIS_TWG->status.st_down;;
		
	}

	void setChecked(bool checked)
	{
		tnSetCheckButtonStatus(THIS_TWG, checked);
	}
};


//////////////////
// Radio button //
//////////////////

#include <QRadioButton>

// Qt radio button

class QIRadioButton : public IRadioButton, public QRadioButton, public QIWidget {

	QI_WIDGET(,QRadioButton)
	
public:
	
	QIRadioButton(QIWidget *parent, const QString &label, int x, int y) : QRadioButton(label)

	{
		rtti_qiradiogroup_parent(QRadioButton);
		QRadioButton::move(x, y);

	};
	
	bool checked() 
	{
		return QRadioButton::isChecked();
	}

	void setChecked(bool checked) 
	{
		QRadioButton::setChecked(checked);
	}
	char* getCaption() const
	{
		return const_cast<char*>(QRadioButton::text().toStdString().c_str());
	}
};

// TWN radio button

class TIRadioButton : public IRadioButton, public TIWidget {

public:
	
	tiobj_constructor(RadioButton, TN_RADIOBUTTON)

	bool checked() {
		return TN_RADIOBUTTONACTIVE(THIS_TWG);
	}

	void setChecked(bool checked) {
		tnSetCheckButtonStatus(THIS_TWG, checked);
	}
	
	char* getCaption() const
	{
		// todo: free ?
		return tnGetWidgetCaption(THIS_TWG);
	}
};

///////////////
// Text box  //
///////////////

#include <QTextEdit>
#include <QList>
#include <QTextCursor>

//todo: #include <QSizePolicy>

// Qt text box

class QITextBox : public ITextBox, public QTextEdit, public QIWidget {
	
	QI_WIDGET(,QTextEdit)
	
public:
	
	QITextBox(QIWidget *parent, const QString &, int x, int y, ITextBox::Mode mode);

	std::string text() 
	{
		return QTextEdit::toPlainText().toStdString(); 
	}

	void setText(const char *txt) 
	{
		const QString t(txt);
		QTextEdit::setPlainText(t);
	}

	void appendText(const char *txt);
	
	void setEditable(bool e) 
	{
		QTextEdit::setReadOnly(!e);
	}

};

// TNW text box

class TITextBox : public ITextBox, public TIWidget
{
public:
	TITextBox(const char *label, TIWidget *parent, int x, int y, ITextBox::Mode mode)
	{
		
		Create(__FILE__, label, TN_TEXTBOX, **parent, x, y, TN_TEXTBOXTYPE, 
		(mode == ITextBox::Single ? TN_SINGLE_LINE : TN_MULTI_LINE), TN_END);
	}

	std::string text() 
	{
		if(THIS_TWG->face.caption)
			return std::string(THIS_TWG->face.caption);
		else
			return std::string();
	}

	void setText(const char *txt)
	{
		tnSetText(THIS_TWG, const_cast<char*>(txt));
	}

	void appendText(const char* txt);

	void setEditable(bool) {
		// todo: ?  notimpl exception
	}	
};

///////////////
// Scrollbar //
///////////////

#include <QScrollBar>

// Qt scrollbar

class QIScrollbar : public IScrollbar, public QScrollBar, public QIWidget {
	
	QI_WIDGET(,QScrollBar)
	
public:
	
	QIScrollbar(QIWidget *parent, const int &x, const int &y, const int &min, 
		const int &max, const int &step, const int &page,
		    IScrollbar::Orientation o);

	int current() 
	{
		return QScrollBar::value();
	}

	void setCurrent(const int &c)
	{
		QScrollBar::setValue(c);
	}

};

// TNW scrollbar

class TIScrollbar : public IScrollbar, public TIWidget {

public:
	TIScrollbar(const char *label, TIWidget *parent, const int &x, const int &y, const int &min,
		    const int &max, const int &step, const int &page, IScrollbar::Orientation o)
	{
		Create(__FILE__, label, TN_SCROLLBAR, **parent, x, y, TN_ORIENTATION, 
			(o == IScrollbar::Vertical ? TN_VERTICAL : TN_HORIZONTAL),
		       TN_MINVAL, min, TN_MAXVAL, max, TN_LINESTEP, step, TN_PAGESTEP, page, TN_END);
	}

	int current() 
	{
		return tnGetThumbPosition(THIS_TWG);
	}

	void setCurrent(const int &c)
	{
		tnSetThumbPosition(THIS_TWG, c);
	}
};

//////////////////
// Progress bar //
//////////////////


#include <QProgressBar>

// Qt progress bar

class QIProgressBar : public IProgressBar, public QProgressBar, public QIWidget {

public:
	QI_WIDGET(,QProgressBar)
	
	QIProgressBar(QIWidget *parent, const int &x, const int &y, const int &min, const int &max, const int &) :
		QProgressBar(parent)
	{
		QProgressBar::move(x, y);
		QProgressBar::setRange(min, max);
		
	}

	int current() const {
		return QProgressBar::value();
	}

	void setCurrent(const int &val)  {
		QProgressBar::setValue(val);
	}
};

// TNW progress bar

class TIProgressBar : public IProgressBar, public TIWidget {

private:
	int cur;
	int max;
	int min;

	const int label_w;
	TILabel *l;

	inline int currentPercent() 
	{
		return ((cur-min) * 100) / (max-min);
	}

public:

	TIProgressBar(TIWidget *parent, const int &x, const int &y, const int &min, const int &max, const int &step) : 
		label_w(30) 
	{
		Create(__FILE__, "", TN_PROGRESSBAR, **parent, x, y, TN_WIDTH, 100, TN_END);
		this->max = max;
		this->min = min;
		this->cur = 0;
		l = new TILabel("0%", parent, x, y);
		l->resize(label_w, 15);
		l->show();
	}

	~TIProgressBar() 
	{
		delete l;
	}

	void resize(int w, int h);

	int current() const 
	{
		return cur;
	}

	void setCurrent(const int &val);
};

////////////////
// Raw widget //
////////////////

// Qt raw widget

class QIRawWidget : public IRawWidget, public QIWidget
{

public:
	QIRawWidget(QIWidget *parent, const QString &, int x, int y) : QWidget(parent)
	{
		move(x, y);
	}
};

// TNW raw widget

class TIRawWidget : public IRawWidget, public TIWidget
{
public:
	tiobj_constructor(RawWidget, TN_RAWWIDGET);
};

////////////
// Drawer //
////////////

#include <QPixmap>
#include <QPainter>

// Qt drawer

class QIDrawer : public IDrawer
{
private:
	QPixmap px;
	QPainter pt;
	QLabel lb;

public:
	QIDrawer(IWidget *srf, int w, int h) : IDrawer(srf), px(w, h), pt(&px),
					       lb(dynamic_cast<QWidget*>(srf))
	{
		// todo: resize pixmap to widget srf size already in iniitalized list
		// and down ere resize label
		// implement getSize methods for IWidgets, both
		
		const QWidget *qwdg = dynamic_cast<QWidget*>(srf);
		px.fill(qwdg, 0, 0);
		
		lb.setPixmap(px);
		lb.show();
	}

	virtual void line(int x1, int y1, int x2, int y2)
	{
		
	}
};

#endif
